package com.mxpio.erp.inventory.service.impl;

import com.alibaba.excel.EasyExcel;
import com.mxpio.erp.common.enums.NoticeStatusEnums;
import com.mxpio.erp.common.enums.OrderEnums;
import com.mxpio.erp.common.inventory.entity.InitStockNotice;
import com.mxpio.erp.common.inventory.entity.InitStockNoticeLine;
import com.mxpio.erp.common.inventory.entity.Lot;
import com.mxpio.erp.common.inventory.entity.Warehouse;
import com.mxpio.erp.common.technology.entity.Item;
import com.mxpio.erp.inventory.service.UploadService;
import com.mxpio.erp.inventory.utils.easyexcel.NoticeExcelListener;
import com.mxpio.erp.inventory.vo.InitStockNoticeImportModel;
import com.mxpioframework.common.exception.MBootException;
import com.mxpioframework.jpa.JpaUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.InputStream;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Author : 吴盼盼
 * @Datetime : 2022/12/29 17:10
 * @Desc :
 * @Modor :  Modifytime:
 * @modDesc :
 */
@Service
public class UploadServiceImpl implements UploadService {
    @Override
    @Transactional
    public List<InitStockNoticeImportModel> uploadInitStockNotice(InputStream inputStream) {
        NoticeExcelListener<InitStockNoticeImportModel> excelListener = new NoticeExcelListener<>();
        EasyExcel.read(inputStream,InitStockNoticeImportModel.class,excelListener).sheet().doRead();
        List<InitStockNoticeImportModel> modelList = excelListener.getList();

        int size = modelList == null ? 0 : modelList.size();
        if (size==0){
            throw new MBootException("上传文件的不能为空或Excle数据都不正确");
        }
        if (size > 10000) {
            throw new MBootException("上传的文件不能超过1万条数据");
        }

        List<String> whCodeList = new ArrayList<>();
        List<String> itemCodeList = new ArrayList<>();
        Set<String> lotNoSet = new HashSet<>();
        modelList.forEach(m -> {
            whCodeList.add(m.getWhCode());
            itemCodeList.add(m.getItemCode());
            if (StringUtils.isNotBlank(m.getLotNo())){
                lotNoSet.add(m.getLotNo());
            }
        });
        List<Warehouse> warehouseList =  JpaUtil.linq(Warehouse.class).in("whCode", whCodeList).list();
        Map<String, Warehouse> warehouseMap = JpaUtil.index(warehouseList,"whCode");//查询仓库
        List<Item> itemList = JpaUtil.linq(Item.class).in("itemCode", itemCodeList).list();
        Map<String, Item> itemMap = JpaUtil.index(itemList,"itemCode");//查询物料
        Set<String> rowIdSet = new HashSet<>();
        Map<String,String> lotNoMap = new HashMap<>();
        List<InitStockNoticeImportModel> succImportModelList = new ArrayList<>();
        Map<String, List<Lot>> dbLotMap = null;
        Map<String, List<InitStockNoticeLine>> dbNoticeLineMap = null;
        if (!lotNoSet.isEmpty()){
            List<Lot> lotList = JpaUtil.linq(Lot.class).in("lotNo", lotNoSet).list();
            if (!lotList.isEmpty()){
                dbLotMap = lotList.stream().collect(Collectors.groupingBy(Lot::getLotNo));
            }

            List<InitStockNoticeLine> dbNoticeLineList = JpaUtil.linq(InitStockNoticeLine.class)
                    .exists(InitStockNotice.class)
                        .equalProperty("noticeNo", "noticeNo")
                        .equal("noticeStatus", NoticeStatusEnums.NoticeStatus.CREATE.getStatusCode())
                    .end()
                    .in("lotNo", lotNoSet).list();
            if (!dbNoticeLineList.isEmpty()){
                dbNoticeLineMap = dbNoticeLineList.stream().collect(Collectors.groupingBy(InitStockNoticeLine::getLotNo));
            }
        }

        for (int i = 0; i < modelList.size(); i++) {
            InitStockNoticeImportModel model = modelList.get(i);
            if (StringUtils.isBlank(model.getWhCode())){
                model.fail("仓库编码为空");
                continue;
            }
            if (StringUtils.isBlank(model.getItemCode())){
                model.fail("物资编码为空");
                continue;
            }
            if (StringUtils.isBlank(model.getLotNo())){
                model.fail("物资批次为空");
                continue;
            }
            if (model.getQuantity()==null||model.getQuantity().compareTo(BigDecimal.ZERO)==0){
                model.fail("数量不能为空或为零");
                continue;
            }
            boolean flag = true;
            StringBuffer sb = new StringBuffer();
            String whCode = model.getWhCode();
            String itemCode = model.getItemCode();
            String lotNo = model.getLotNo();
            String rowIdStr = whCode+"_"+itemCode+"_"+lotNo;
            if (!warehouseMap.containsKey(whCode)){
                flag = false;
                sb.append("仓库编码不存在;");
            }
            if (!itemMap.containsKey(itemCode)){
                flag = false;
                sb.append("物资编码不存在;");
            }
            if (lotNoMap.containsKey(lotNo)){
                String usedItemCode = lotNoMap.get(lotNo);
                if (!StringUtils.equals(usedItemCode,itemCode)){
                    flag = false;
                    sb.append("存在一个批次号对应多个物料;");
                }
            }else{
                lotNoMap.put(lotNo,itemCode);
            }
            if (dbLotMap!=null&&dbLotMap.containsKey(lotNo)){
                flag = false;
                sb.append("批次号再系统中存在;");
            }
            if (dbNoticeLineMap!=null&&dbNoticeLineMap.containsKey(lotNo)){
                flag = false;
                sb.append("批次号在其他未提交通知单明细中已存在;");
            }
            if (rowIdSet.contains(rowIdStr)){
                flag = false;
                sb.append("存在仓库和物料批次相同的其他行数据;");
            }else{
                rowIdSet.add(rowIdStr);
            }
            if (flag) {
                model.setImportSuccess("成功");
                model.setImportMsg("导入成功");
            } else {
                model.setImportSuccess("失败");
                model.setImportMsg(sb.toString());
                continue;
            }
            succImportModelList.add(model);
        }
        //处理验证通过数据
        if (!succImportModelList.isEmpty()){
            Map<String, List<InitStockNoticeImportModel>> map = succImportModelList.stream().collect(Collectors.groupingBy(InitStockNoticeImportModel::getWhCode));
            for (String whCode: map.keySet()){//根据仓库维度 生成对应的仓单
                List<InitStockNoticeImportModel> submodelList = map.get(whCode);
                InitStockNotice initStockNotice = new InitStockNotice();
                initStockNotice.setNoticeDate(new Date());
                initStockNotice.setWhCode(whCode);
                initStockNotice.setAccessType(OrderEnums.AccessType.IN.getCode());
                initStockNotice.setPickingType(NoticeStatusEnums.NoticeType.INIT_IN.getCode());//初始入库
                initStockNotice.setNoticeStatus(NoticeStatusEnums.NoticeStatus.CREATE.getStatusCode());//默认开立
                JpaUtil.save(initStockNotice);
                List<InitStockNoticeLine> lineList = new ArrayList<>();
                int lineNo = 0;
                for (InitStockNoticeImportModel per:submodelList){
                    InitStockNoticeLine line = new InitStockNoticeLine();
                    lineNo++;
                    line.setNoticeNo(initStockNotice.getNoticeNo());
                    line.setLineNo(lineNo+"");
                    Item item = JpaUtil.linq(Item.class).idEqual(per.getItemCode()).findOne();
                    line.setItemName(item.getItemName());
                    line.setItemSpec(item.getItemSpec());
                    line.setUnitCode(item.getUnitCode());
                    line.setQuantity(per.getQuantity());
                    line.setItemCode(per.getItemCode());
                    line.setMemo(per.getNote());
                    line.setLotNo(per.getLotNo());//指定批次
                    lineList.add(line);
                }
                if (lineList.size()>0){
                    JpaUtil.save(lineList);
                }
            }
        }
        return modelList;
    }
}
